#include "MorphologyAction.h"
#include "MorphologyDilation.h"
#include "MorphologyErosion.h"
#include "MorphologyOpen.h"
#include "MorphologyClose.h"


MorphologyAction::MorphologyAction ()
: AbstractAction (), _structElem (QSize (1, 1)), _curMorphologyType (0)
{
	_structElem (0, 0) = 1;
	_morphologyPtrList.push_back (new MorphologyDilation (_structElem));
	_morphologyPtrList.push_back (new MorphologyErosion (_structElem));
	_morphologyPtrList.push_back (new MorphologyOpen (_structElem));
	_morphologyPtrList.push_back (new MorphologyClose (_structElem));
}



void MorphologyAction::setStructElem (const Core< int > & structElem)
{
	_structElem = structElem;
}



Core< int > & MorphologyAction::getStructElem ()
{
	return _structElem;
}



const Core< int > & MorphologyAction::getStructElem () const
{
	return _structElem;
}



void MorphologyAction::updatePreview (QRect viewport)
{
	_pMorphology = _morphologyPtrList[_curMorphologyType];
	_pMorphology->setStructElem (_structElem);

	Ptr< Layer > pCurLayer = __pTargetWork->getDoc ()->getCurrentLayer ();

	bool isPreview = true;
	if (viewport.isEmpty ()) {
		isPreview = false;
		viewport = pCurLayer->getRegion ();
	}

	QRect updateRegion = viewport & pCurLayer->getRegion ();

	QPoint oSrcImg = pCurLayer->getRegion ().topLeft ();
	QPoint oViewport = viewport.topLeft ();
	QPoint oUpdate = updateRegion.topLeft ();

	QRect processRegion = updateRegion;
	processRegion.translate (-oSrcImg);

	Ptr< QImage > pProcessSrc = new QImage (pCurLayer->getImage ()
			->copy (processRegion));
	Ptr< QImage > pProcessResult = _pMorphology->operate (pProcessSrc);

	// Draw preview image
	Ptr< QImage > pPreview = new QImage (viewport.size (),
			QImage::Format_ARGB32);
	pPreview->fill (0);

	for (int v = updateRegion.top (); v <= updateRegion.bottom (); ++v) {
		QRgb * previewLine = (QRgb *)pPreview->scanLine (v - oViewport.y ());
		QRgb * resultLine = (QRgb *)pProcessResult->scanLine (
				v - oUpdate.y ());
		memcpy (&resultLine[updateRegion.left () - oViewport.x ()],
				resultLine, updateRegion.width () * sizeof (QRgb));
	}

	if (isPreview)
		pCurLayer->setPreviewImage (pProcessResult);
	else
		pCurLayer->setImage (pProcessResult);

}



void MorphologyAction::handleStartEvent ()
{
	__pTargetWork->getDoc ()->getCurrentLayer ()->openPreview ();
}



void MorphologyAction::rejectAction ()
{
	__pTargetWork->getDoc ()->getCurrentLayer ()->closePreview ();
}



void MorphologyAction::applyAction ()
{
	updatePreview (QRect ());
	__pTargetWork->getDoc ()->getCurrentLayer ()->closePreview ();
}



void MorphologyAction::setActionType (int t)
{
	_curMorphologyType = t;
}


